if not orders then


if not ScriptsRootPath then
	ScriptsRootPath = getScriptPath() .. "\\..\\"
end


dofile (ScriptsRootPath .. "lib\\lib.lua")

dofile (ScriptsRootPath .. "processor\\processor.lua")
dofile (ScriptsRootPath .. "processor\\OnTransReply.lua")
dofile (ScriptsRootPath .. "processor\\OnOrder.lua")
dofile (ScriptsRootPath .. "processor\\OnStopOrder.lua")
dofile (ScriptsRootPath .. "processor\\log.lua")


orders =	{
				queue = {},
				transactions = {count = 0},
				orders = {count = 0},
				OnTransReplyHandlers = {},
				OnOrderHandlers = {},
				OnStopOrderHandlers = {},
				stop_replaced = {},
				log = function() end
			}


dofile (ScriptsRootPath .. "lib\\orders.transaction.lua")
dofile (ScriptsRootPath .. "lib\\orders.limit.lua")
dofile (ScriptsRootPath .. "lib\\orders.stop.lua")
dofile (ScriptsRootPath .. "lib\\orders.load.lua")
dofile (ScriptsRootPath .. "lib\\orders.save.lua")
dofile (ScriptsRootPath .. "lib\\orders.lock.lua")
			
			
orders.log = function(...) processor:log(...) end
--orders.log = function(...) message(...) end


function orders:IsOrder(order)
	if type(order) == "table"
		and order.order_num
		and order.sec_code
		--and bit.test(order.flags, 0) 
		and lib.global.class_codes[order.class_code]
		--and order.trans_id >= 1000000
		--and order.trans_id < 2000000
		and (order.expiry <= 0								-- 0 - GTC, -1 - today
			or order.expiry == int(lib:FormatDate())		-- today
			--or order.expiry == -1
			--or order.EXPIRY_DATE == "TODAY"
		)
	then
		return order
	end
	--orders.log("IsOrder false", lib:FormatDate(), order)
end


processor:AddHandler("OnTransReply", function(trans_reply)
	local transaction = orders.transactions[tostring(trans_reply.trans_id)]
	
	orders.log("OnTransReply", trans_reply, transaction)
	
	orders:CallHandlers("OnTransReplyHandlers", trans_reply, transaction)
	
	if not transaction then return end
	
	orders:lock_queue()
	
	local count = orders.transactions.count
	
	if trans_reply.status == 3 then		-- done
		local key = tostring(trans_reply.order_num)
		
		if int(key) ~= 0 then
			transaction.ex__.key = key
		end
		
		if orders:IsNewStop(transaction) or orders:IsNewLimit(transaction) then
			local q = orders.orders[transaction.ex__.key]
			
			if not q then
				q = {}
				orders.orders[transaction.ex__.key] = q
				orders:lock_queue()
				orders.orders.count = orders.orders.count + 1
			end
			
			q.transaction = transaction
			q.trans_reply = trans_reply
			
			if q.order then
				if orders:IsNewLimit(transaction) then
					orders:OnOrder(q.order, q.transaction, q.trans_reply)
				elseif orders:IsNewStop(transaction) then
					orders:OnStopOrder(q.order, q.transaction, q.trans_reply)
				end
			end
		end
		
		if transaction.next_transaction__ then
			orders.log("Send Next Transaction")
			
			orders:sendNext(transaction.next_transaction__)
		end
	else
		processor:log("OnTransReplyHandler error", trans_reply, "", transaction)
		
		if trans_reply.status == 4
			and trans_reply.error_code == 102
			and orders:IsActivatedStop(transaction)
			and not transaction.ex__.resend
		then
			transaction.BASE_ORDER_KEY = nil
			transaction.ACTIVATE_IF_BASE_ORDER_PARTLY_FILLED = nil
			transaction.USE_BASE_ORDER_BALANCE = nil
			
			local kinds = {
				ACTIVATED_BY_ORDER_SIMPLE_STOP_ORDER = "SIMPLE_STOP_ORDER",
				ACTIVATED_BY_ORDER_TAKE_PROFIT_AND_STOP_LIMIT_ORDER = "TAKE_PROFIT_AND_STOP_LIMIT_ORDER"
			}
			transaction.STOP_ORDER_KIND = kinds[transaction.STOP_ORDER_KIND]
			
			transaction.ex__.resend = true
			
			orders:sendNext(transaction)
		end
	end
	
	orders.transactions[tostring(trans_reply.trans_id)] = nil
	orders.transactions.count = orders.transactions.count - 1
	orders:unlock_queue()
	
	orders.log("Transaction Queue", orders.transactions)
	
	if count > 0 and orders.transactions.count == 0 then
		for k, q in pairs(orders.orders) do
			if type(q) == "table" and (not q.transaction or not q.trans_reply) then
				orders.log(message("Clean Orders Queue " .. k))
				orders.orders[k] = nil
				orders.orders.count = orders.orders.count - 1
				orders:unlock_queue()
			end
		end
	end
	
	orders:sendQueue()
	orders:unlock_queue()
end)


processor:AddHandler("OnOrder", function(order)
	if not orders:IsOrder(order) then return end
	
	orders.log("OnOrder", order)
	
	local q = orders.orders[tostring(order.order_num)]
	
	if not q and orders.transactions.count > 0 then
		q = {}
		orders.orders[tostring(order.order_num)] = q
		orders:lock_queue()
		orders.orders.count = orders.orders.count + 1
	end
	
	if q then
		q.order = order
		
		if q.transaction and q.trans_reply then
			orders:OnOrder(q.order, q.transaction, q.trans_reply)
		end
	end
end)


processor:AddHandler("OnStopOrder", function(order)
	if not orders:IsOrder(order) then return end
	
	orders.log("OnStopOrder", order)
	
	local q = orders.orders[tostring(order.order_num)]
	
	if not q and orders.transactions.count > 0 then
		q = {}
		orders.orders[tostring(order.order_num)] = q
		orders:lock_queue()
		orders.orders.count = orders.orders.count + 1
	end
	
	if q then
		q.order = order
		
		if q.transaction and q.trans_reply then
			orders:OnStopOrder(q.order, q.transaction, q.trans_reply)
		end
	end
end)


function orders:OnOrder(order, transaction, trans_reply)
	if transaction.ex__.take_limit then
		orders:SaveTakeLimit(orders:GetTakeLimitStopID(transaction.ex__.take_limit), order.order_num)
	else
		orders:SaveTransaction(transaction)
		
		orders:CallHandlers("OnOrderHandlers", order, transaction, trans_reply)
	end
		
	orders.orders[tostring(order.order_num)] = nil
	orders.orders.count = orders.orders.count - 1
	
	orders:sendQueue()
	orders:unlock_queue()
end


function orders:OnStopOrder(order, transaction, trans_reply)
	if transaction.ex__.take_limit then
		orders:SaveTakeLimit(order.order_num, orders:GetTakeLimitID(transaction.ex__.take_limit))
	end
	
	orders:CallHandlers("OnStopOrderHandlers", order, transaction, trans_reply)
	
	orders.orders[tostring(order.order_num)] = nil
	orders.orders.count = orders.orders.count - 1
	
	orders:sendQueue()
	orders:unlock_queue()
end


function orders:CallHandlers(name, data1, data2)
	if not name then return end
	
	for i, v in ipairs(self[name]) do
		v(self, data1, data2)
	end
end


function orders:AddOnLimitStopHandler()
	if not self.on_limit_stop_handler then
		self.on_limit_stop_handler = function(self, order, transaction)
			self.log("OnOrderHandler", order, transaction)
			
			if not transaction then return end
			
			if self:IsNewLimit(transaction)
				and transaction.ex__.lm
				and transaction.ex__.sl
				and not transaction.ex__.take_limit
			then
				local state = bit.band(order.flags, 3)
				
				if state == 1 then -- active
					if transaction.ex__.tp then
						self:SendActivatedTakeStop(transaction)
					else
						self:SendActivatedStop(transaction)
					end
				elseif state == 0 then -- executed
					if transaction.ex__.tp then
						self:SendTakeStop(transaction)
					else
						self:SendStop(transaction)
					end
				end
			end
		end
		
		table.sinsert(self.OnOrderHandlers, self.on_limit_stop_handler)
	end
end


end -- of file
